<!--
  Copyright JS Foundation and other contributors, http://js.foundation

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<script type="text/x-red" data-template-name="tcp in">
    <div class="form-row">
        <label for="node-input-server"><i class="fa fa-dot-circle-o"></i> <span data-i18n="tcpin.label.type"></span></label>
        <select id="node-input-server" style="width:120px; margin-right:5px;">
            <option value="server" data-i18n="tcpin.type.listen"></option>
            <option value="client" data-i18n="tcpin.type.connect"></option>
        </select>
        <span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width:65px">
    </div>
    <div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;">
        <span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" placeholder="localhost" style="width: 60%;">
    </div>

    <div class="form-row">
        <label><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.output"></span></label>
        <select id="node-input-datamode" style="width:110px;">
            <option value="stream" data-i18n="tcpin.output.stream"></option>
            <option value="single" data-i18n="tcpin.output.single"></option>
        </select>
        <select id="node-input-datatype" style="width:140px;">
            <option value="buffer" data-i18n="tcpin.output.buffer"></option>
            <option value="utf8" data-i18n="tcpin.output.string"></option>
            <option value="base64" data-i18n="tcpin.output.base64"></option>
        </select>
        <span data-i18n="tcpin.label.payload"></span>
    </div>

    <div id="node-row-newline" class="form-row hidden" style="padding-left:110px;">
        <span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;">
    </div>

    <div class="form-row">
        <label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
        <input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic">
    </div>
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
        <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
    </div>
</script>

<script type="text/x-red" data-help-name="tcp in">
    <p>Provides a choice of TCP inputs. Can either connect to a remote TCP port,
       or accept incoming connections.</p>
    <p><b>Note: </b>On some systems you may need root or administrator access
    to access ports below 1024.</p>
</script>

<script type="text/javascript">
    RED.nodes.registerType('tcp in',{
        category: 'input',
        color:"Silver",
        defaults: {
            name: {value:""},
            server: {value:"server",required:true},
            host: {value:"",validate:function(v) { return (this.server == "server")||v.length > 0;} },
            port: {value:"",required:true,validate:RED.validators.number()},
            datamode:{value:"stream"},
            datatype:{value:"buffer"},
            newline:{value:""},
            topic: {value:""},
            base64: {/*deprecated*/ value:false,required:true}
        },
        inputs:0,
        outputs:1,
        icon: "bridge-dash.png",
        label: function() {
            return this.name || "tcp:"+(this.host?this.host+":":"")+this.port;
        },
        labelStyle: function() {
            return this.name?"node_label_italic":"";
        },
        oneditprepare: function() {
            var updateOptions = function() {
                var sockettype = $("#node-input-server").val();
                if (sockettype == "client") {
                    $("#node-input-host-row").show();
                } else {
                    $("#node-input-host-row").hide();
                }
                var datamode = $("#node-input-datamode").val();
                var datatype = $("#node-input-datatype").val();
                if (datamode == "stream") {
                    if (datatype == "utf8") {
                        $("#node-row-newline").show();
                    } else {
                        $("#node-row-newline").hide();
                    }
                } else {
                    $("#node-row-newline").hide();
                }
            };
            updateOptions();
            $("#node-input-server").change(updateOptions);
            $("#node-input-datatype").change(updateOptions);
            $("#node-input-datamode").change(updateOptions);
        }
    });
</script>


<script type="text/x-red" data-template-name="tcp out">
    <div class="form-row">
        <label for="node-input-beserver"><i class="fa fa-dot-circle-o"></i> <span data-i18n="tcpin.label.type"></span></label>
        <select id="node-input-beserver" style="width:150px; margin-right:5px;">
            <option value="server" data-i18n="tcpin.type.listen"></option>
            <option value="client" data-i18n="tcpin.type.connect"></option>
            <option value="reply" data-i18n="tcpin.type.reply"></option>
        </select>
        <span id="node-input-port-row"><span data-i18n="tcpin.label.port"></span> <input type="text" id="node-input-port" style="width: 65px"></span>
    </div>

    <div class="form-row hidden" id="node-input-host-row" style="padding-left: 110px;">
        <span data-i18n="tcpin.label.host"></span> <input type="text" id="node-input-host" style="width: 60%;">
    </div>

    <div class="form-row hidden" id="node-input-end-row">
        <label>&nbsp;</label>
        <input type="checkbox" id="node-input-end" style="display: inline-block; width: auto; vertical-align: top;">
        <label for="node-input-end" style="width: 70%;"><span data-i18n="tcpin.label.close-connection"></span></label>
    </div>

    <div class="form-row">
        <label>&nbsp;</label>
        <input type="checkbox" id="node-input-base64" placeholder="base64" style="display: inline-block; width: auto; vertical-align: top;">
        <label for="node-input-base64" style="width: 70%;"><span data-i18n="tcpin.label.decode-base64"></span></label>
    </div>

    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
        <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
    </div>
</script>

<script type="text/x-red" data-help-name="tcp out">
    <p>Provides a choice of TCP outputs. Can either connect to a remote TCP port,
    accept incoming connections, or reply to messages received from a TCP In node.</p>
    <p>Only the <code>msg.payload</code> is sent.</p>
    <p>If <code>msg.payload</code> is a string containing a Base64 encoding of binary
    data, the Base64 decoding option will cause it to be converted back to binary
    before being sent.</p>
    <p>If <code>msg._session</code> is not present the payload is
    sent to <b>all</b> connected clients.</p>
    <p><b>Note: </b>On some systems you may need root or administrator access
    to access ports below 1024.</p>
</script>

<script type="text/javascript">
    RED.nodes.registerType('tcp out',{
        category: 'output',
        color:"Silver",
        defaults: {
            host: {value:"",validate:function(v) { return (this.beserver != "client")||v.length > 0;} },
            port: {value:"",validate:function(v) { return (this.beserver == "reply")||RED.validators.number()(v); } },
            beserver: {value:"client",required:true},
            base64: {value:false,required:true},
            end: {value:false,required:true},
            name: {value:""}
        },
        inputs:1,
        outputs:0,
        icon: "bridge-dash.png",
        align: "right",
        label: function() {
            return this.name || "tcp:"+(this.host?this.host+":":"")+this.port;
        },
        labelStyle: function() {
            return (this.name)?"node_label_italic":"";
        },
        oneditprepare: function() {
            var updateOptions = function() {
                var sockettype = $("#node-input-beserver").val();
                if (sockettype == "reply") {
                    $("#node-input-port-row").hide();
                    $("#node-input-host-row").hide();
                    $("#node-input-end-row").hide();
                } else {
                    $("#node-input-port-row").show();
                    $("#node-input-end-row").show();
                }

                if (sockettype == "client") {
                    $("#node-input-host-row").show();
                } else {
                    $("#node-input-host-row").hide();
                }
            };
            updateOptions();
            $("#node-input-beserver").change(updateOptions);
        }
    });
</script>


<script type="text/x-red" data-template-name="tcp request">
    <div class="form-row">
        <label for="node-input-server"><i class="fa fa-globe"></i> <span data-i18n="tcpin.label.server"></span></label>
        <input type="text" id="node-input-server" placeholder="ip.address" style="width:45%">
        <span data-i18n="tcpin.label.port"></span>
        <input type="text" id="node-input-port" style="width:60px">
    </div>
    <div class="form-row">
        <label for="node-input-out"><i class="fa fa-sign-out"></i> <span data-i18n="tcpin.label.return"></span></label>
        <select type="text" id="node-input-out" style="width:54%;">
            <option value="time" data-i18n="tcpin.return.timeout"></option>
            <option value="char" data-i18n="tcpin.return.character"></option>
            <option value="count" data-i18n="tcpin.return.number"></option>
            <option value="sit" data-i18n="tcpin.return.never"></option>
            <option value="immed" data-i18n="tcpin.return.immed"></option>
        </select>
        <input type="text" id="node-input-splitc" style="width:50px;">
        <span id="node-units"></span>
    </div>
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
        <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
    </div>
</script>

<script type="text/x-red" data-help-name="tcp request">
    <p>A simple TCP request node - sends the <code>msg.payload</code> to a server tcp port and expects a response.</p>
    <p>Connects, sends the "request", and reads the "response". It can either count a number of
    returned characters into a fixed buffer, match a specified character before returning,
    wait a fixed timeout from first reply and then return, sit and wait for data, or send then close the connection
    immediately, without waiting for a reply.</p>
    <p>The response will be output in <code>msg.payload</code> as a buffer, so you may want to .toString() it.</p>
    <p>If you leave tcp host or port blank they must be set by using the <code>msg.host</code> and <code>msg.port</code> properties.</p>
</script>

<script type="text/javascript">
    RED.nodes.registerType('tcp request',{
        category: 'function',
        color:"Silver",
        defaults: {
            server: {value:""},
            port: {value:"",validate:RED.validators.regex(/^(\d*|)$/)},
            out: {value:"time",required:true},
            splitc: {value:"0",required:true},
            name: {value:""}
        },
        inputs:1,
        outputs:1,
        icon: "bridge-dash.png",
        label: function() {
            return this.name || "tcp:"+(this.server?this.server+":":"")+this.port;
        },
        labelStyle: function() {
            return this.name?"node_label_italic":"";
        },
        oneditprepare: function() {
            var previous = null;
            $("#node-input-out").on('focus', function () { previous = this.value; }).change(function() {
                if (previous === null) { previous = $("#node-input-out").val(); }
                if ($("#node-input-out").val() == "char") {
                    if (previous != "char") { $("#node-input-splitc").val("\\n"); }
                    $("#node-units").text("");
                }
                else if ($("#node-input-out").val() == "time") {
                    if (previous != "time") { $("#node-input-splitc").val("0"); }
                    $("#node-units").text(RED._("node-red:tcpin.label.ms"));
                }
                else if ($("#node-input-out").val() == "immed") {
                    if (previous != "immed") { $("#node-input-splitc").val(" "); }
                    $("#node-units").text("");
                }
                else if ($("#node-input-out").val() == "count") {
                    if (previous != "count") { $("#node-input-splitc").val("12"); }
                    $("#node-units").text(RED._("node-red:tcpin.label.chars"));
                }
                else {
                    if (previous != "sit") { $("#node-input-splitc").val(" "); }
                    $("#node-units").text("");
                }
            });
        }
    });
</script>
